﻿using DeHeng_Mes.Constant;
using DeHeng_Mes.Dao;
using DeHeng_Mes.Dao.PlcDao;
using DeHeng_Mes.Model;
using DeHeng_Mes.Model.Boss;
using DeHeng_Mes.Model.BossModel;
using DeHeng_Mes.Model.ConfigModel;
using DeHeng_Mes.Model.OrderSingleton;
using DeHeng_Mes.Model.PlcModel;
using DeHeng_Mes.Model.PlcModel.door_01;
using DeHeng_Mes.Model.Table;
using DeHeng_Mes.Model.ViewModel;
using DeHeng_Mes.PlcService;
using DeHeng_Mes.Service;
using DeHeng_Mes.Utils;
using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using NPOI.SS.Formula.Eval;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Utilities;
using S7.Net;
using SqlSugar;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reactive.Concurrency;
using System.Reflection;
using System.Runtime.InteropServices.ComTypes;
using System.ServiceModel.Description;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Documents;
using W03_UI.Table;
using MappingTable = DeHeng_Mes.Utils.MappingTable;
using Type = System.Type;

namespace DeHeng_Mes.Thread
{
    public class LinePlcToMes
    {
        #region 全局成员
        OrderDao orderDao = new OrderDao();
        PlcDao plcDao = new PlcDao();

        EntranceService entranceService = new EntranceService();
        ExitService exitService = new ExitService();
        VerificationService verificationService = new VerificationService();
        SpotCheakService spotCheakService = new SpotCheakService();
        ErrorType errortype = new ErrorType();
        QueryDataDao dataDao = new QueryDataDao();
        #endregion

        /// <summary>
        /// 处理读取完成的信号，将追溯码与订单、节拍等信息绑定
        /// </summary>
        /// <param name="types">数据类型字典</param>
        /// <param name="orderModel">工单模型</param>
        public bool ProcessOkStatus(Dictionary<object, Type> types, PlcOrderConfigModel orderModel)
        {
            int index = 0;

            // 初始化报警码
            List<int> errorCodes = new List<int>();

            // 初始化反馈结果
            int isOk = 0;

            // 初始化状态字段
            string stationStatus = $"{orderModel.PlcName}-STATUS";



            // 获取该Plc工位状态数组信息
            Tuple<int, int> byteTuple = MappingTable.GetBytesOff(stationStatus);

            Tuple<int, int> returnByteTuple = MappingTable.GetReturnBytesOff(stationStatus);

            if (byteTuple == null && returnByteTuple == null)
                return true;

            // 读取状态数组数据
            byte[] bytes = orderModel.plc.ReadBytes(DataType.DataBlock, byteTuple.Item1, SystemConstant.ALL_STARTOFF, byteTuple.Item2);

            byte[] returnBytes = orderModel.plc.ReadBytes(DataType.DataBlock, returnByteTuple.Item1, SystemConstant.ALL_STARTOFF, returnByteTuple.Item2);

            // 获取状态字段对应偏移量
            Dictionary<string, Tuple<int, int>> fieldOffs = MappingTable.GetDicByName(stationStatus);

            // 获取二维码数据
            Dictionary<string, object> codeDic = plcDao.GetFieldValues(types, SystemConstant.CODE);

            string status = "";

            string station = "";

            string typeString = string.Empty;

            foreach (var fieldOff in fieldOffs)
            {
                string result = "";

                Stopwatch stopwatch = Stopwatch.StartNew();

                try
                {
                    station = fieldOff.Key;


                    // 获取最新状态
                    status = bytes[fieldOff.Value.Item1].ToString();

                    // 获取旧状态
                    (string oldStatus, byte returnByte) = orderModel.StatusDic[station];

                    string operationId = MappingTable.GetOperationId(station);

                    // 获取过程数据数组
                    Tuple<int, int> tuple = MappingTable.GetStationOff(station);

                    if (!fieldOff.Key.Contains("NG"))
                    {
                        if (tuple == null)
                            continue;

                        // 读取数组信息
                        byte[] stationBytes = orderModel.plc.ReadBytes(DataType.DataBlock, tuple.Item1, SystemConstant.ALL_STARTOFF, tuple.Item2);

                        // 获取工站过程数据
                        //StationData data = PlcDataUtil.FromBytesToClass(stationBytes, MappingTable.GetDicByName(station), station);

                        List<int> resultOffs = MappingTable.GetResultOff(orderModel.PlcName, station);

                        int resultDbEndOff = 0;

                        int resultDb = 0;

                        switch (orderModel.PlcName)
                        {
                            case "DOOR-01":
                                resultDbEndOff = 32;

                                resultDb = 5002;
                                break;
                            case "DOOR-02":
                                resultDbEndOff = 39;

                                resultDb = 5002;
                                break;
                            case "DOOR-03":
                                resultDbEndOff = 532;

                                resultDb = 5040;
                                break;
                            case "DOOR-04":
                                resultDbEndOff = 532;

                                resultDb = 5040;
                                break;
                        }

                        if (station.Equals("Op90L"))
                        {

                        }

                        foreach (var item in resultOffs)
                        {
                            switch (orderModel.plc.ReadBytes(DataType.DataBlock, resultDb, SystemConstant.ALL_STARTOFF, resultDbEndOff)[item])
                            {
                                case 1:
                                    result = result.Equals("") ? "OK" : $"{result},OK";
                                    break;
                                case 0:
                                    result = result.Equals("") ? "NA" : $"{result},NA";
                                    break;
                                default:
                                    result = result.Equals("") ? "NG" : $"{result},NG";
                                    break;
                            }
                        }
                    }



                    // 获取二维码
                    string code = GetTraceId(types, station);

                    try
                    {
                        if (status.Equals("3"))
                        {
                            returnByte = 2;
                        }

                        // 对比新旧状态，无变化则跳过
                        if (oldStatus.Equals(status))
                            continue;

                        stopwatch.Start();

                        if ((!status.Equals("4") && !status.Equals("0")) && string.IsNullOrEmpty(code))
                        {
                            Tools.ProduceLogTextError($"[{station}]，二维码为空，当前状态[{status}]");
                        }

                        switch (status)
                        {
                            // 校验
                            case "1":
                                typeString = "校验";
                                break;
                            // 入站
                            case "2":
                                typeString = "入站";
                                break;
                            // 出站
                            case "3":
                                typeString = "出站";
                                break;
                            // 信号复位
                            case "4":
                                typeString = "信号复位";
                                break;
                            // 点检
                            case "5":
                                typeString = "点检";
                                break;
                            // 补序
                            case "6":
                                typeString = "补序";
                                break;
                            // 补结束时间
                            case "7":
                                typeString = "结束时间增补";
                                break;
                            default:
                                typeString = "未知";
                                code = status;
                                break;
                        }

                        Tools.ProduceLogText($"[{station}]触发[{typeString}]状态，关联码[{code}]");

                        if (status.Equals("1") || status.Equals("2") || status.Equals("3")/* || status.Equals("5") || status.Equals("6") || status.Equals("7")*/)
                        {
                            /*if (string.IsNullOrEmpty(code))
                            {
                                Tools.ProduceLogTextError($"[{station}]在[{status}]阶段丢码");

                                continue;
                            }*/
                        }

                        switch (status)
                        {
                            // 校验
                            case "1":
                                // 执行校验
                                returnByte = verificationService.CodeVerification(station, code, operationId);

                                Tools.ProduceLogTextError(station + "写入信号为" + returnByte);

                                // 校验成功 执行备份
                                orderDao.BackUpCode(code, station);
                                break;
                            // 入站
                            case "2":
                                entranceService.StationEntrance(station, code, operationId);
                                break;
                            // 出站
                            case "3":
                                returnByte = exitService.StationExit(station, bytes, code, result, operationId);

                                if (returnByte == 2 && !station.Contains("NG"))
                                    BandingOrderIdAndTraceCode(code, station);

                                // 获取工位对应的数据块
                                string operation = MappingTable.GetOperationNo(orderModel.PlcName, station);

                                // 获取保存DB信息的二元组
                                Tuple<int, int> dbTuple = MappingTable.GetBytesOff($"{orderModel.PlcName}-{operation}");

                                byte[] dataBytes = null;

                                if (dbTuple != null)
                                {
                                    // 读取数组信息
                                    dataBytes = orderModel.plc.ReadBytes(DataType.DataBlock, dbTuple.Item1, SystemConstant.ALL_STARTOFF, dbTuple.Item2);
                                }

                                // 读取该工位相关工艺参数
                                ReadOperationData(station, orderModel, dataBytes, operation, code);
                                break;
                            case "4":
                                //returnByte = 0;
                                break;
                            // 点检
                            case "5":
                                returnByte = spotCheakService.StationSpotChackSave(station, index, orderModel, plcDao.GetStringFieldValue(types, "Check", station + "_1"));
                                break;
                            // 补序
                            /*case "6":
                                returnByte = errortype.InsertStation(station, code, orderModel);
                                break;
                            // 补结束时间
                            case "7":
                                returnByte = errortype.InsertEndStation(station, code, orderModel);
                                break;*/
                            default:
                                returnByte = 0;
                                break;
                        }

                        stopwatch.Stop();

                        long elapsedMilliseconds = stopwatch.ElapsedMilliseconds;

                        Tools.ProduceLogText($"[{station}]本次执行响应耗时[{elapsedMilliseconds}]MS");
                    }
                    finally
                    {
                        // 记录状态与返回值
                        orderModel.StatusDic[station] = (status, returnByte);

                        // 获取对应工位的已读信号
                        int off = MappingTable.GetReadOff(station);

                        // 写入对应的已读信号
                        orderModel.plc.Write(DataType.DataBlock, 5001, off, returnByte);

                        /*// 信号置位
                        if (!status.Equals("3"))
                        {
                            // 获取已读信号
                            if (returnBytes[off].ToString().Equals("2"))
                                // 写入对应的已读信号
                                orderModel.plc.Write(DataType.DataBlock, 5001, off, 0);
                        }*/
                    }
                }
                catch (Exception e)
                {
                    Tools.ProduceLogTextError($"[{station}]:" + e.Message);
                }
            }
            return true;
        }

        /// <summary>
        /// 获取精追码
        /// </summary>
        /// <param name="types"></param>
        /// <param name="station"></param>
        /// <returns></returns>
        private string GetTraceId(Dictionary<object, Type> types, string station)
        {


            return plcDao.GetStringFieldValue(types, SystemConstant.CODE, station + $"_1").Trim();
        }

        /// <summary>
        /// 操作工单绑定追溯码
        /// </summary>
        /// <param name="traceCode"></param>
        /// <param name="station"></param>
        private void BandingOrderIdAndTraceCode(string traceCode, string station)
        {
            List<OrderSingletonModel> orderModels = OrderSingleton.Instance;

            if (orderModels?.Count > 0)
            {
                string materialId = station.Contains("L") ? "100401002102" : "100401002103";

                orderModels.Where(o => o.MaterialId == materialId)
                           .ToList()
                           .ForEach(order => orderDao.BandingOrderAndTraceCode(traceCode, order.OrderId, station));
            }
        }

        /// <summary>
        /// 处理需要从Plc中读取的工艺数据
        /// </summary>
        /// <param name="station"></param>
        /// <param name="plcModel"></param>
        /// <param name="bytes"></param>
        /// <param name="operation"></param>
        /// <param name="code"></param>
        private void ReadOperationData(string station, PlcOrderConfigModel orderModel, byte[] bytes, string operation, string code)
        {
            _ = Task.Run(() =>
            {
                if (!string.IsNullOrEmpty(operation))
                {
                    // 根据工艺判断需要从Plc读取的工艺数据
                    switch (operation)
                    {
                        case "GLUE":
                            GetGlueDataSave(station, bytes, code, operation);
                            break;
                        case "WELD":
                            GetSpotWeldDataSave(station, bytes, code);
                            break;
                        case "POINT":
                            GetPointDataSave(station, bytes, code);
                            break;
                        case "CCD":
                            GetCCDDataSave(station, bytes, code);
                            break;
                    }
                }
                else if (!string.IsNullOrEmpty(station))
                {
                    // 查询FDS数据
                   // List<FdsDataToDataGirl> fdsValue = FdsDataQuery(code, station);

                    // 查询拧紧数据
                    List<TightenData> tightenDatas = TightenDataQuery(code, station);

                    // 推送FDS数据
                   // _ = Task.Run(() => { ViewService.InsertLineMesData(code, station, fdsValue); });

                    // 推送拧紧数据
                    _ = Task.Run(() => { ViewService.InsertLineMesData(code, station, tightenDatas); });
                }
            });
        }

        /// <summary>
        /// 拧紧数据查询方法
        /// </summary>
        /// <param name="code"></param>
        /// <param name="station"></param>
        private List<TightenData> TightenDataQuery(string code, string station)
        {
            // 初始化Tighten数据
            List<TightenData> tightenDatas = new List<TightenData>();

            try
            {
                if (station.Equals(SystemConstant.OP170L) ||
                station.Equals(SystemConstant.OP170R))
                {
                    if (string.IsNullOrEmpty(code) && !code.Contains(" "))
                        return tightenDatas;

                    string[] codes = code.Split(' ');

                    string traceId = $"{codes[0].Substring(codes[0].Length - 6)}{codes[4]}{codes[5]}";

                    Task<string> jsonTask = APIGetData(traceId, station);

                    string jsonData = jsonTask.Result;

                    List<ModelContainer> modelContainers = JsonConvert.DeserializeObject<List<ModelContainer>>(jsonData);

                    if (modelContainers == null)
                    {
                        Tools.ProduceLogTextError($"[{station}]未查询到拧紧数据，追溯码为[{code}]");

                        return tightenDatas;
                    }

                    foreach (ModelContainer modelContainer in modelContainers)
                    {
                        TightenData tighten = new TightenData();

                        tighten.Id = modelContainer.Id;

                        tighten.DeviceName = modelContainer.Model.DeviceName;

                        tighten.PSetNumber = modelContainer.Model.PSet.Number.ToString();

                        tighten.TorqueTarget = modelContainer.Model.Results[0].Steps[0].Configuration.torqueTarget.ToString();

                        tighten.FinalTorque = modelContainer.Model.Results[0].Steps[0].Data.FinalTorque.ToString();

                        tighten.FinalAngle = modelContainer.Model.Results[0].Steps[0].Data.FinalAngle.ToString();

                        tighten.ErrorCode = modelContainer.Model.Results[0].Steps[0].Data.errorCode.ToString().Equals("0") ? "OK" : "NG";

                        tighten.StopSource = modelContainer.Model.Results[0].Steps[0].Data.stopSource.ToString();

                        tighten.Code = code;

                        tightenDatas.Add(tighten);
                    }
                }
            }
            catch (Exception e)
            {
                Tools.ProduceLogTextError($"[{station}]查询拧紧数据失败，原因是{e.Message}");
            }
            
            return tightenDatas;
        }

        /// <summary>
        /// FDS数据查询方法
        /// </summary>
        /// <param name="code"></param>
        /// <param name="station"></param>
        private List<FdsDataToDataGirl> FdsDataQuery(string code, string station)
        {
            // FDS数据集合
            List<FdsDataToDataGirl> fdsDataToDataGirls = new List<FdsDataToDataGirl>();

            try
            {
                if (
                station.Equals(SystemConstant.OP180L) ||
                station.Equals(SystemConstant.OP180R)
                )
                {
                    if (string.IsNullOrEmpty(code) && !code.Contains(" "))
                        return (fdsDataToDataGirls);

                

                    string[] codes = code.Split(' ');
                    

                    string traceId = $"{codes[0].Substring(codes[0].Length - 6)}{codes[4]}{codes[5]}";

                    List<TraceFDS> fdsData = dataDao.GetFDSDtlData(traceId);

                    if (fdsData?.Count > 0)
                    {
                        try
                        {
                            List<long> indexList = fdsData.Select(x => long.Parse(x.AutoIndex)).ToList();

                            List<TraceFdsStep> fdsStep = dataDao.GetFdsStep(indexList);

                            foreach (var item in fdsData)
                            {
                                foreach (var step in fdsStep.Where(x => x.AutoProgIndex == int.Parse(item.AutoIndex)).ToList())
                                {
                                    FdsDataToDataGirl fdsDataToDataGirl = new FdsDataToDataGirl()
                                    {
                                        SystemId = item.SystemId,
                                        OK_NOK_Code = item.OK_NOK_Code,
                                        StartTime = item.StartTime,

                                        Name = step.Name,
                                        Parameter = step.Parameter,
                                        StepIndex = step.StepIndex,
                                        IoNio = step.IoNio,
                                    };

                                    fdsDataToDataGirls.Add(fdsDataToDataGirl);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Tools.ProduceLogTextError($"[{station}]组装FDS数据失败，原因是{ex.Message}");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Tools.ProduceLogTextError($"[{station}]查询FDS数据失败，原因是{e.Message}");
            }

            return fdsDataToDataGirls;
        }

        /// <summary>
        /// 读取并保存125CCD数据
        /// </summary>
        /// <param name="station"></param>
        /// <param name="bytes"></param>
        /// <param name="code"></param>
        private void GetCCDDataSave(string station, byte[] bytes, string code)
        {
            try
            {
                Dictionary<string, int> dic = MappingTable.GetCCDOff(station);

                List<TraceCCD> trace = new List<TraceCCD>();

                if (dic != null)
                {
                    for (int i = 0; i < dic["Off"]; i++)
                    {
                        TraceCCD traceCCD = new TraceCCD();

                        traceCCD.TraceId = code;
                        traceCCD.Station = station;
                        /*traceCCD.PointName = (i + 1).ToString();*/
                        byte[] bytes1 = bytes.Skip(dic["Number"]+(i*34)).Take(30).ToArray();

                        traceCCD.PointName = Encoding.ASCII.GetString(bytes1, 2, bytes1[1]);

                        traceCCD.Result = S7.Net.Types.Byte.FromByteArray(bytes.Skip(dic["Result"] + (i * 34)).Take(1).ToArray()).ToString();
                        traceCCD.CreateTime = DateTime.Now;

                        trace.Add(traceCCD);
                    }

                    orderDao.SaveCCDData(trace, code);

                    Tools.ProduceLogText($"[{station}]存储了[{trace.Count}]条CCD数据");

                    _ = Task.Run(() => { ViewService.InsertLineMesData(code, station, trace); });
                }
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError($"{station}工位CCD工艺数据保存失败，请检查，原因是：{ex.Message}");
            }
        }

        /// <summary>
        /// 读取并保存打刻数据
        /// </summary>
        /// <param name="station"></param>
        /// <param name="bytes"></param>
        /// <param name="code"></param>
        private void GetPointDataSave(string station, byte[] bytes, string code)
        {
            // 实例化数据封装类
            PointData pointData = new PointData()
            {
                Code = code,
                Station = station,
            };

            switch (station)
            {
                case "Op160L_2":

                    pointData.PointCode = Encoding.UTF8.GetString(bytes.Skip(188).Take(64).ToArray()).Replace("\0", "").Trim();

                    break;
                case "Op160R_2":

                    pointData.PointCode = Encoding.UTF8.GetString(bytes.Skip(440).Take(64).ToArray()).Replace("\0", "").Trim();

                    break;
            }

            // 判断打刻数据是否插入
            if (!orderDao.PointDataIsSave(code, station))
                orderDao.PointDataSave(pointData);
        }

        /// <summary>
        /// 读取并保存点焊数据
        /// </summary>
        /// <param name="station"></param>
        /// <param name="bytes"></param>
        /// <param name="code"></param>
        private void GetSpotWeldDataSave(string station, byte[] bytes, string code)
        {
            try
            {
                // 获取点焊偏移量
                Dictionary<string, int> weldData = MappingTable.GetWeldOff(station);

                List<TraceSpotWeld> traceSpotWelds = new List<TraceSpotWeld>();

                for (int i = 0; i < weldData["Off"]; i++)
                {
                    // 封装数据
                    TraceSpotWeld traceSpotWeld = new TraceSpotWeld();

                    int weldTime = S7.Net.Types.Int.FromByteArray(bytes.Skip(weldData["WeldTime"] + 18 * i).Take(2).ToArray());

                    traceSpotWeld.TraceId = code;
                    traceSpotWeld.Station = station;
                    traceSpotWeld.ErrorCode = S7.Net.Types.Byte.FromByteArray(bytes.Skip(weldData["ErrorCode"] + 18 * i).Take(1).ToArray()).ToString();
                    traceSpotWeld.Num = S7.Net.Types.Byte.FromByteArray(bytes.Skip(weldData["Num"] + 18 * i).Take(1).ToArray()).ToString();
                    traceSpotWeld.ReHotTime = S7.Net.Types.Int.FromByteArray(bytes.Skip(weldData["ReHotTime"] + 18 * i).Take(2).ToArray()).ToString();
                    traceSpotWeld.ReHotA = S7.Net.Types.Int.FromByteArray(bytes.Skip(weldData["ReHotA"] + 18 * i).Take(2).ToArray()).ToString();
                    traceSpotWeld.ReHotV = S7.Net.Types.Int.FromByteArray(bytes.Skip(weldData["ReHotV"] + 18 * i).Take(2).ToArray()).ToString();
                    traceSpotWeld.WeldTime = weldTime.ToString();
                    traceSpotWeld.WeldA = S7.Net.Types.Int.FromByteArray(bytes.Skip(weldData["WeldA"] + 18 * i).Take(2).ToArray()).ToString();
                    traceSpotWeld.WeldV = S7.Net.Types.Int.FromByteArray(bytes.Skip(weldData["WeldV"] + 18 * i).Take(2).ToArray()).ToString();
                    traceSpotWeld.R = S7.Net.Types.Int.FromByteArray(bytes.Skip(weldData["R"] + 18 * i).Take(2).ToArray()).ToString();
                    traceSpotWeld.StatusNo = S7.Net.Types.Byte.FromByteArray(bytes.Skip(weldData["StatusNo"] + 18 * i).Take(1).ToArray()).ToString();
                    traceSpotWeld.Result = S7.Net.Types.Byte.FromByteArray(bytes.Skip(weldData["Result"] + 18 * i).Take(1).ToArray()).ToString();
                    traceSpotWeld.CreateTime = DateTime.Now;

                    traceSpotWeld.PulseCount = (weldTime / 200).ToString();

                    traceSpotWelds.Add(traceSpotWeld);
                }

                orderDao.SaveWeldSpot(traceSpotWelds, code, station);

                // 点焊数据推送
                _ = Task.Run(() => { ViewService.InsertLineMesData(code, station, traceSpotWelds); });
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError($"{station}工位点焊工艺数据保存失败，请检查，原因是：{ex.Message}");
            }
        }

        /// <summary>
        /// 读取并保存涂胶数据
        /// </summary>
        /// <param name="station"></param>
        /// <param name="bytes"></param>
        /// <param name="operation"></param>
        /// <param name="code"></param>
        private void GetGlueDataSave(string station, byte[] bytes, string code, string operation)
        {
            try
            {
                Dictionary<string, int> dic = MappingTable.GetGlueOff(station);

                if (dic != null && bytes != null)
                {
                    List<TraceGlue> traceGlues = new List<TraceGlue>();

                    for (int i = 0; i < dic["Off"]; i++)
                    {
                        TraceGlue traceGlue = new TraceGlue();

                        traceGlue.TraceId = code;
                        traceGlue.Station = station;
                        traceGlue.RangeNo = S7.Net.Types.Int.FromByteArray(bytes.Skip(dic["RangeNo"] + 34 * i).Take(2).ToArray()).ToString();
                        traceGlue.StartTime = S7.Net.Types.DateTime.FromByteArray(bytes.Skip(dic["StartTime"] + 34 * i).Take(8).ToArray()).ToString();
                        traceGlue.EndTime = S7.Net.Types.DateTime.FromByteArray(bytes.Skip(dic["EndTime"] + 34 * i).Take(8).ToArray()).ToString();
                        traceGlue.Press = S7.Net.Types.Real.FromByteArray(bytes.Skip(dic["Press"] + 34 * i).Take(4).ToArray()).ToString();
                        traceGlue.Speed = S7.Net.Types.Real.FromByteArray(bytes.Skip(dic["Speed"] + 34 * i).Take(4).ToArray()).ToString();
                        traceGlue.Amount = S7.Net.Types.Real.FromByteArray(bytes.Skip(dic["Amount"] + 34 * i).Take(4).ToArray()).ToString();
                        traceGlue.Temperature = S7.Net.Types.Real.FromByteArray(bytes.Skip(dic["Temperature"] + 34 * i).Take(4).ToArray()).ToString();

                        traceGlues.Add(traceGlue);
                    }

                    orderDao.GlueDataSave(traceGlues, code, station);

                    // 涂胶数据推送
                    _ = Task.Run(() => { ViewService.InsertLineMesData(code, station, traceGlues); });
                }
            }
            catch (Exception ex)
            {
                Tools.ProduceLogTextError($"{station}工位涂胶工艺数据保存失败，请检查，原因是：{ex.Message}");
                
            }
        }

        /// <summary>
        /// 调用接口获取拧紧数据
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public async Task<string> APIGetData(string code, string station)
        {
            string jsonData = string.Empty;

            try
            {
                // 创建 HttpClient 实例
                using (HttpClient client = new HttpClient())
                {
                    // 创建请求的基础地址
                    var baseUrl = "http://localhost:20080/getdata/v1/tighteningresults";

                    // 创建查询字符串
                    var queryString = $"?vin={code}&includeCurve=true&includeSteps=false";

                    // 构造完整的请求 URL
                    var requestUrl = baseUrl + queryString;

                    // 发送 GET 请求并获取响应
                    var response = await client.GetAsync(requestUrl).ConfigureAwait(false);

                    // 确保响应成功
                    if (response.IsSuccessStatusCode)
                    {
                        // 读取响应内容
                        jsonData = await response.Content.ReadAsStringAsync();
                    }
                    else
                    {
                        // 处理错误
                        Tools.ProduceLogTextError($"请求失败：{response.StatusCode}");
                    }
                }
            }
            catch (Exception e)
            {
                Tools.ProduceLogTextError($"[{station}]请求拧紧数据失败，原因是[{e.Message}]，追溯码为[{code}]");
            }

            return jsonData;
        }
    }
}